<?php


namespace app\community\oauth2\Model;


use app\cms\community\lib\QueryModel;
use app\community\oauth2\Exception\ClientException;
use app\community\oauth2\Exception\ClientNotFoundException;
use iflow\Response;
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;

class oauthClientRefreshAccessTokenModel extends QueryModel
{
    protected $table = 'oauth_client_refresh_access_token_table';

    /**
     * 保存AccessToken
     * @param RefreshTokenEntityInterface $refreshTokenEntity
     * @return Response
     * @throws ClientException
     */
    public function saveRefreshAccessToken(RefreshTokenEntityInterface $refreshTokenEntity): Response
    {
        $save = $this->createData([
            'app_id' => $refreshTokenEntity -> getAccessToken() -> getClient() -> getIdentifier(),
            'app_refresh_access_token' => $refreshTokenEntity -> getIdentifier(),
            'app_access_token' => $refreshTokenEntity -> getAccessToken() -> getIdentifier(),
            'expired' => $refreshTokenEntity -> getExpiryDateTime() -> getTimestamp()
        ]);
        if ($save -> data['code'] !== 200) {
            throw new ClientException($save -> data['msg'], $save -> data['code']);
        }
        return $save;
    }

    /**
     * 撤销 RefreshAccessToken
     * @param string $refreshToken
     * @return Response
     */
    public function revokeRefreshAccessToken(string $refreshToken): Response
    {
        return $this->deleteData([
            'app_id' => request() -> params('client_id'),
            'app_refresh_access_token' => $refreshToken
        ]);
    }

    /**
     * 验证RefreshAccessToken是否过期
     * @param string $refreshToken
     * @return bool
     * @throws ClientNotFoundException
     */
    public function validateRefreshAccessToken(string $refreshToken): bool
    {
        $accessToken = $this->findInfo([
            'app_id' => request() -> params('client_id'),
            'app_refresh_access_token' => $refreshToken
        ]);

        if (!$accessToken) {
            throw new ClientNotFoundException('Invalid RefreshAccessToken', 401);
        }

        if ($accessToken['expired'] < time()) {
            throw new ClientNotFoundException('RefreshAccessToken has expired', 401);
        }

        return false;
    }

}